//
// Created by xumy on 2021/8/8.
//

#include "iostream"
#include "string"
#include "vector"
#include "cstdlib"
#include "stdexcept"

using namespace std;

template<class T>
class Stack {
private:
    vector<T> elems;

public:
    void push(T const &);

    void pop();

    T top() const;

    bool empty() const {
        return elems.empty();
    }
};

template<class T>
void Stack<T>::push(T const &elem) {
    elems.push_back(elem);
}

template<class T>
void Stack<T>::pop() {
    if (elems.empty()) {
        throw out_of_range("pop failed, empty stack");
    }
    elems.pop_back();
}

template<class T>
T Stack<T>::top() const {
    if (elems.empty()) {
        throw out_of_range("top failed: empty stack");
    }
    return elems.back();
}

int main() {
    try {
        Stack<int> iStack;
        Stack<string> strStack;

        iStack.push(5);
        cout << iStack.top() << endl;
        
        strStack.push("hello");
        cout << strStack.top() << endl;
        strStack.pop();
        strStack.pop();
    } catch (exception const &ex) {
        cerr << "Exception " << ex.what() << endl;
        return -1;
    }

    return 0;
}